package pro.cherish.knowledgedemoaop.aop;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import pro.cherish.knowledgedemoaop.annotation.AutoFillEntityFieldAopAnnotation;

/**
 * @author 创建人：cherish
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2019-09-28 cherish 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：WebLogAcpect6
 * @Description 功能说明：
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2019-09-28 cherish
 */
@Aspect
@Component
@Slf4j
public class WebLogAcpect6 {


    /**
     * 切点
     */
    @Pointcut("@annotation(pro.cherish.knowledgedemoaop.annotation.AutoFillEntityFieldAopAnnotation)")
    public void daoAop() {
    }

    // 切点函数也可以是有参数的，可&&放在@annotation中，可以将arg获取参数，在通知方法中daoAop（XXX,XXX）将参数获取到


    /**
     * &&符号用于传参
     * 3） this：用于向通知方法中传入代理对象的引用。
     *
     * @Before(“before() && this(proxy)”)
     * public void beforeAdvide(JoinPoint point, Object proxy){
     * //处理逻辑
     * }
     * <p>
     * 4）target：用于向通知方法中传入目标对象的引用。
     * @Before(“before() && target(target)
     * public void beforeAdvide(JoinPoint point, Object proxy){
     * //处理逻辑
     * }
     * <p>
     * 5）args：用于将参数传入到通知方法中。
     * @Before(“before() && args(age,username)”)
     * public void beforeAdvide(JoinPoint point, int age, String username){
     * //处理逻辑
     * }
     */

    @Before("daoAop() && this(proxy)")
    public void beforeAdvide(JoinPoint point, Object proxy) {
        System.out.println();
        //处理逻辑
    }

    @AfterReturning("daoAop() && target(target)")
    public void afterAdvice(JoinPoint point, Object target) {
        System.out.println();
        //处理逻辑
    }


    /**
     * 自动填值
     *
     * @param joinPoint 切面方法
     * @return 返回值
     */
    @Around("daoAop() && @annotation(autoFillEntityFieldAopAnnotation)")
    public Object doAround(ProceedingJoinPoint joinPoint, AutoFillEntityFieldAopAnnotation autoFillEntityFieldAopAnnotation) {
        // 可以根据注解传递的值进行对注解进行归类，不同的注解使用不同策略处理
        String s = autoFillEntityFieldAopAnnotation.methodType();
        System.out.println(autoFillEntityFieldAopAnnotation);
        Object[] orgs = {1, "123"};
        Object result = null;
        try {
            // 执行原方法，可改造((Tcontroller6)joinPoint.getTarget()).say("abdddc"); 直接执行其他方法
            result = joinPoint.proceed(orgs);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }


}
